#!/usr/bin/env python
# -*- coding: utf-8 -*- 

import sys
from os import walk, getcwd, chdir
import os.path
from optparse import OptionParser
import unittest
from warnings import warn
import doctest
import string

import trace
import sys

MODUL_PATH = '.'

options = [{'noms':('-r', '--repertoire'), 'dest':'rep',
          'help':('Spécifie le répertoire à utiliser, si non fourni,'
                  ' le chemin \'%s\' est utilisé' % (MODUL_PATH))}]

def _print_line():
    print '-' * 70
    
    



def main(option, arguments, parser):
    if options.rep is not None:
        chemin = options.rep
    else:
        if len(arguments) > 0:
            print parser.usage
            sys.exit(2)
        #chemin=getcwd()
        chemin = MODUL_PATH
    
    #add le chemin au path pour les imports des sous repertoires.
    if not os.path.exists(MODUL_PATH):
        raise 'modul no found.'
    abschemin = os.path.abspath(MODUL_PATH)
    (abschemin, tail) = os.path.split(abschemin)
    sys.path.append(abschemin)
    #print sys.path

    chemin = os.path.normpath(chemin)
    if chemin.endswith(os.path.sep):
        chemin = chemin[:-1]
    
    
    print 'parcours du répertoire'
    test_modules = []
    for racine, reps, fichiers in walk(chemin):
        for fichier in fichiers:
            if ((fichier.endswith('.py') or fichier.endswith('.txt')) and fichier not in ('test.py', 'test.txt')):
                nom_complet = os.path.join(racine, fichier)
                tests = os.path.basename(racine) == 'tests'
                test_modules.append((nom_complet, fichier.split('.')[0], tests))
                sys.stdout.write('.')
                sys.stdout.flush()
                
                
    print '\n%d modules(s) de test trouvé(s)\n' % len(test_modules)
    
    suite = unittest.TestSuite()
    dernier_contexte = None
    added_paths = []   
                
    
    for fichier, module, dossier_tests in test_modules:
        #print fichier, dossier_tests
        module_path = os.path.dirname(fichier)
        if module_path not in sys.path:
            sys.path.append(module_path)
            added_paths.append(module_path)
            
        if dossier_tests:
            contexte = os.path.join(module_path, 'contexte.py')
        else:
            contexte = os.path.join(module_path, 'tests_contexte.py')
            
        if fichier.endswith('.txt') and dossier_tests:
            doc_file_suite = doctest.DocFileSuite(fichier, module_relative=False)
            suite.addTest(doc_file_suite)
            continue
        
        if module.startswith('test') and dossier_tests:
            m = __import__(module)
            if 'get_test_class' in m.__dict__:
                try:
                    class_type = m.get_test_class()
                    test_suite = unittest.TestSuite((unittest.makeSuite(class_type),))
                    suite.addTest(test_suite)
                except TypeError:
                    for class_type in m.get_test_class():
                        test_suite = unittest.TestSuite((unittest.makeSuite(class_type),))
                        suite.addTest(test_suite)
                
            else:
                warn("%s n'a pas de fonction get_test_class" % fichier)
                
        if not dossier_tests and fichier.endswith('.py'):
#            print fichier, dossier_tests
            m = __import__(module)
            try:
                doc_test_suite = doctest.DocTestSuite(m)
#                print "%s, %s"%(module,m)
            except ValueError:
#                print "erreur import docTest %s: %s, %s"%(module,fichier, m)
                pass
            else:
                suite.addTest(doc_test_suite)            
                
    nb_test_case = suite.countTestCases()
    if nb_test_case == 0:
        print 'Aucun test.'
        sys.exit(2)
    
    print '\nLancement de %d test(s)...' % nb_test_case
    _print_line()
    campagne = unittest.TextTestRunner(verbosity=2)
    campagne.run(suite)
    
    for added_path in added_paths:
        sys.path.remove(added_path)
            
if __name__ == '__main__':
       
    parser = OptionParser()
    parser.usage = """test [-r repertoire]
exemple :
    test.py
ou
    test.py -r src/pyamelet/model/"""
    for option in options:
        param = option['noms']
        del option['noms']
        parser.add_option(*param, **option)
    options, arguments = parser.parse_args()
    sys.argv[:] = arguments

    
    main(option, arguments, parser)
        
